<?php

/**
 * Bootstrap
 *
 * Главный системный класс, используется для настройки и запуска приложения
 *
 * @author Игорь Будасов aka Lord <igor.budasov@gmail.com>
 */

require_once 'Zend/Loader/Autoloader.php';


class Bootstrap
{
	/**
	 * Объект конфигурации
	 *
	 * @var Zend_Config
	 */
	private $_config = null;

/*------------------------------------------------------------------------------*/

	/**
	 * Запуск приложения
	 *
	 * @var array $config Конфигурация
	 */

	public function run($config)
	{
		try {
			// ставим такую штуку, чтоб кавычки и слэши не превращались в миллион слэшей
			ini_set('magic_quotes', 'off');

			// Настройка загрузчика
			$this->setLoader();

            // Проверим лицензию
            $this->setLicense();
            
			// Настройка конфигурации
			$this->setConfig($config);
			// Запуск кэширования всей страницы
			// $this->setCache();
			// Настройка Вида
			$this->setView();
			 /*
			// стартуем сессию
			require_once 'Zend/Session.php';
			Zend_Session::start();
			 */
			// Подключение к базе данных
			$this->setDbAdapter();

			// Подключение маршрутизации
			$router = $this->setRouter();

			// подключаем дебаггер
			//Zend_Loader::loadClass('Zend_Debug');

			// подключаем класс аутентификации
			Zend_Loader::loadClass('Zend_Auth');

			// Создание объекта front контроллера
			$front = Zend_Controller_Front::getInstance();
			//$front->setParam('noViewRenderer', true);
			// Подключаем плагин, управляющий правами
			//$front->registerPlugin(new Lord_Plugin_Acl(new Acl()));
			$front->registerPlugin(Lord_Plugin_Acl::getInstance(Acl::getInstance()));

			// Добавляем каталог с модулями
			$front->addModuleDirectory($this->_config->path->modules);

			// Настройка front контроллера, указание базового URL, правил маршрутизации
			$front->setBaseUrl($this->_config->url->base)
				  ->throwexceptions(true)
				  ->setRouter($router);

			// Устанавливаем префикс для помощников действий
			Zend_Controller_Action_HelperBroker::addPrefix('Lord_Action_Helper');

			// запускаем переводчик
			$this->setTranslator();

			// панелька дебага. Если не нужна - закомментируй
			// $this->_initZFDebug();


			// Запуск приложения, в качестве параметра передаем путь к папке с контроллерами
			// Zend_Controller_Front::run($this->_config->path->controllers);


			Zend_Registry::set('front', $front);
			//  Запуск приложения
			$front->dispatch();


		}
		catch (Zend_Exception $e) { 
			// Перехват исключений
			Error::catchException($e);
		}
	}

/*------------------------------------------------------------------------------*/

	/**
	 * Настройка загрузчика
	 */

	public function setLoader()
	{
		// Запуск автозагрузки
		$autoloader = Zend_Loader_Autoloader::getInstance();
		$autoloader->setFallbackAutoloader(true);
		//Zend_Loader::registerAutoload();
	}

/*------------------------------------------------------------------------------*/

	/**
	 * Настройка конфигурации
	 *
	 * @param array $config Настройки
	 */

	public function setConfig($config)
	{
		$config = new Zend_Config($config);
		$this->_config = $config;
		Zend_Registry::set('config', $config);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Настраиваем Переводчик
	*/

	public function setTranslator()
	{
		$lang = 'ru';

		$translate = new Zend_Translate('array',
										// подключаем перевод
										$this->_config->path->languages . $lang . '.php',
										// язык по умолчанию
										$lang,
										array(
										// Тип автоматического определения переводов
										'scan'=>Zend_Translate::LOCALE_FILENAME
										));
		// Получаем текущую локаль
		$locale = $translate->getLocale();
		// Файл перевода
		$source = $this->_config->path->languages . $locale . '.php';
		// Передаем путь к файлу и локаль, к которой он относится
		$translate->addTranslation($source,$locale);
		// Задаем транслятор для Zend_Validate,
		// чтобы все ошибки валидации выводились
		// пользователю на нужном языке
		Zend_Validate_Abstract::setDefaultTranslator($translate);
		// устанавливаем локаль. Это переключатель языка
		//$translate->setLocale('ru');
		// запускаем процесс перевода
		Zend_Registry::set('Zend_Translate', $translate);
	}

/*------------------------------------------------------------------------------*/

	/**
	 * Настройка вида
	 */

	public function setView()
	{
		//require 'Smarty/Smarty.class.php';

		// Инициализация Zend_Layout, настройка пути к макетам,
		// а также имени главного макета.
		// Параметр layout указан лишь для примера, по умолчанию имя макета именно "layout"

		Zend_Layout::startMvc(array(
			'layoutPath' => $this->_config->path->layouts,
			'layout'     => 'layout',
		));

		// Получение объекта Zend_Layout
		$layout = Zend_Layout::getMvcInstance();

		// Инициализация объекта Zend_View
		// $view = $layout->getView();


		// Настройка расширения макетов
		$layout->setViewSuffix('tpl');

		$applicationDir = $GLOBALS['root'] . 'application/';
		$templateDir    = $GLOBALS['root'] . 'design/';
		$compileDir     = $GLOBALS['root'] . 'temporary/templates_c/';
		$pluginsDir     = $GLOBALS['root'] . 'application/library/Smarty/plugins/';
		$configsDir     = $GLOBALS['root'] . 'application/library/Smarty/configs/';
		$scriptPath     = $GLOBALS['root'] . 'application/modules/:module/views/:controller/:action.:suffix';

		$view = new Lord_View_Smarty_Smarty($templateDir,
									 array('compile_dir'     => $compileDir,
										   'smartyClass'     => 'SmartyAdvanced',
										   'plugins_dir'     => $pluginsDir,
										   'config_dir'      => $configsDir,
										   'scripts_path'    => $scriptPath,
										   ));

		$view->baseUrl    = $this->_config->url->base;
		$view->imagesUrl  = $this->_config->url->images;
		$view->cssUrl     = $this->_config->url->css;
		$view->jsUrl      = $this->_config->url->js;
		$view->fontsUrl   = $this->_config->url->fonts;
		$view->contentUrl = $this->_config->url->content;
		$view->siteName   = $this->_config->common->siteName;
		$view->scriptPath = $scriptPath;

		// подключаем доджо
		// $view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
		// Устанавливаем путь/префикс для помощников вида
		$view->addHelperPath('Lord/View/Helper/', 'Lord_View_Helper');
		// Добавляем путь для скриптов вида акшн-хэлперов
		$view->addBasePath($this->_config->path->layouts);

		$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
		$viewRenderer->setView($view)
			 ->setViewBasePathSpec($templateDir)
			 ->setViewScriptPathSpec($scriptPath)
			 ->setViewScriptPathNoControllerSpec(':action.:suffix')
			 ->setViewSuffix('tpl')
			 ;

		// смотрим, есть ли залогиненый юзер
		$view->user = Zend_Auth::getInstance()->getIdentity();

		// Установка объекта Zend_View
		$layout->setView($view);

		Zend_Registry::set('smarty', $view);
		Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
	}

/*------------------------------------------------------------------------------*/

	/**
	 * Установка соединения с базой данных и помещение его объекта в реестр.
	 */

	public function setDbAdapter()
	{
		// Подключение к БД, так как Zend_Db "понимает" Zend_Config,
		// нам достаточно передать специально сформированный объект
		// конфигурации в метод factory
		$db = Zend_Db::factory($this->_config->db);

		// Задание адаптера по умолчанию для наследников класса Zend_Db_Table_Abstract
		Zend_Db_Table_Abstract::setDefaultAdapter($db);
		/*
		$cache = Zend_Cache::factory('Core', 'File', array('automatic_serialization' => true,
														   'lifetime' => 3600*12),
														   array('cache_dir' => 'temporary/cache/base'));
		Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
		*/

		// Занесение объекта соединения c БД в реестр
		Zend_Registry::set('db', $db);
	}

/*------------------------------------------------------------------------------*/

    /**
     * Настройка маршрутов
     */

    public function setRouter()
    {
        // Подключение файла правил маршрутизации
        require($this->_config->path->system . 'routes.php');

        // Если переменная router не является объектом
        // Zend_Controller_Router_Abstract, выбрасываем исключение
        if (!($router instanceof Zend_Controller_Router_Abstract)) {
            throw new Exception('Incorrect config file: routes');
        }
        Zend_Registry::set('router', $router);
        return $router;
    }

/*------------------------------------------------------------------------------*/

	/**
	 * Проверка лицензии
	 */

	public function setLicense()
	{
		$license = new License();
//        $license->set('user@domain.com', 'www.profit-engine.pp.ua,profit-engine.pp.ua,profit.com,profit.local,localhost,zend.local', 9999999);
        if(!$license->check())
        {
            echo '<center><h1><br><br><br><br><br><br><br>License invalid</h1></center>'; 
            exit;
        }
        return;
	}

/*------------------------------------------------------------------------------*/

	/**
	* Настройка кэширования всей страницы
	*/

	public function setCache()
	{
	  /*
	  * Вы должны избегать слишком большого количества строк кода перед этим участком
	  * кэша. Например, для наибольшей производительности "require_once" или
	  * "Zend_Loader::loadClass" должны находиться после кэшируемого участка
	  */

	  $frontendOptions = array(
		 'lifetime' => 7200,
		 'debug_header' => true, // для отладки
		 'cache_with_get_variables'=>true,
		 'cache_with_cookie_variables' => true,
		   'regexps' => array(
				   '^/$' => array('cache' => true),
				   '^/store/' => array('cache' => true),
				   '^/goods/' => array('cache' => true),
				   )
	  );

	  $backendOptions = array(
		  'cache_dir' => 'temporary/cache/scripts' // директория, в которой размещаются файлы кэша
	  );

	  // получение объекта Zend_Cache_Frontend_Page
	  $cache = Zend_Cache::factory('Page',
								   'File',
								   $frontendOptions,
								   $backendOptions);

	  $cache->start();
	  return;
	  // если есть попадание в кэш, результат отправляется броузеру,
	  // и выполнение скрипта на этом завершается
	  // [...] конец загрузочного файла
	  // (этот код не исполняется, если есть попадание в кэш)
	}

/*------------------------------------------------------------------------------*/

	/**
	* Прикольная панелька дебаггера
	* не уверен, что нужна, но пусть будет
	*/

	protected function _initZFDebug()
	{
		$autoloader = Zend_Loader_Autoloader::getInstance();
		$autoloader->registerNamespace('ZFDebug');
		$db = Zend_Db::factory($this->_config->db);
		$options = array(
			'plugins' => array(
				'Variables',
				'File' => array('base_path' => '/'),
				'Memory',
				'Time',
				'Registry',
				'Exception',
				'Html',
				'Database' => array('adapter' => $db)
			)
		);


		/*
		// Настройка плагина для кеша
		if ($this->hasPluginResource('cache')) {
			$this->bootstrap('cache');
			$cache = $this-getPluginResource('cache')->getDbAdapter();
			$options['plugins']['Cache']['backend'] = $cache->getBackend();
		}
		*/
		$debug = new ZFDebug_Controller_Plugin_Debug($options);

		//$this->bootstrap('frontController');
		$frontController = Zend_Controller_Front::getInstance();
		$frontController->registerPlugin($debug);
	}

/*------------------------------------------------------------------------------*/
}
